package flights.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Type;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import flights.bi.Flight;
import flights.bi.FlightWithAirline;
import flights.db.FlightHandler;

/**
 * Servlet implementation class FlightServlet
 */
public class FlightServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		String url = request.getPathInfo();
		response.setContentType( "text/html" ); 
		if (url != null && url.indexOf("get") != -1)
		{
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			List<Flight> flights = null;
			try {
				flights = FlightHandler.getAllFlights();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(flights));	
			return;
		}
		if (url != null && url.indexOf("airline") != -1)
		{
			String airline_id = request.getParameter("airid");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			List<Flight> flights = null;
			try {
				flights = FlightHandler.getAllFlightsByAirline(airline_id);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.print(gson.toJson(flights));
			return;
		}
		if (url != null && url.indexOf("dest") != -1)
		{
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			ArrayList<String> dests = new ArrayList<String>();
			List<Flight> flights = new ArrayList<Flight>();
			try {
				flights = FlightHandler.getAllFlights();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (Flight flight : flights) {
				if (!dests.contains(flight.getArrival_airport()))
				{
					dests.add(flight.getArrival_airport());
				}
			}
			out.print(gson.toJson(dests));	
		}
		if (url != null && url.indexOf("src") != -1)
		{
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			ArrayList<String> src = new ArrayList<String>();
			List<Flight> flights = new ArrayList<Flight>();;
			try {
				flights = FlightHandler.getAllFlights();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (Flight flight : flights) {
				if (!src.contains(flight.getDepart_airport()))
				{
					src.add(flight.getArrival_airport());
				}
			}
			out.print(gson.toJson(src));	
		}
		if (url != null && url.indexOf("qparams") != -1)
		{
			String start = request.getParameter("start");
			String end = request.getParameter("end");
			String depart = request.getParameter("depart");
			String arrive = request.getParameter("arrive");
			String mincost = request.getParameter("mincost");
			String maxcost = request.getParameter("maxcost");
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			Date dtStart = null;
			Date dtEnd  = null;
			if (start != null)
			{
				dtStart = Date.valueOf(start);
			}
			if (end != null)
			{
				dtEnd = Date.valueOf(end);
			}
			
			Integer min = null;
			if (mincost != null)
			{
				min = Integer.parseInt(mincost);
			}
			Integer max = null;
			if (maxcost != null)
			{
				max = Integer.parseInt(maxcost);
			}
			
			List<FlightWithAirline> flights_with_air = new ArrayList<FlightWithAirline>();
			List<Flight> flights = new ArrayList<Flight>();;
			try {
				flights = FlightHandler.getFlightByparameters(min, max, depart, arrive, dtStart, dtEnd);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (Flight flight : flights) {
				try {
					flights_with_air.add(new FlightWithAirline(flight));
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			out.print(gson.toJson(flights_with_air));	
		}
		if (url != null && url.indexOf("remove") != -1)
		{
			String flightId = request.getParameter("fid");
			int nRows = 0;
			try {
				nRows = FlightHandler.deleteFlightByID(Integer.parseInt(flightId));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.write("{\"status\":" + nRows + "}");
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		String url = request.getPathInfo();
		response.setContentType( "text/html" ); 
		StringBuilder sb = new StringBuilder();
	    BufferedReader br = request.getReader();
	    String str;
	    
	    while( (str = br.readLine()) != null ){
	        sb.append(str);
	    }    
	    String flightJson = sb.toString();
		if (url != null && url.indexOf("update") != -1)
		{
			Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
			if (flightJson != null && !flightJson.isEmpty()) {
				
				Type flightType = new TypeToken<Flight>(){}.getType();
				Flight flight = gson.fromJson(flightJson, flightType);
				
				int nRows = 0;
				try {
					nRows = FlightHandler.upsertFlight(flight);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				out.write("{\"status\":" + nRows + "}");
			}
		}
		else if (url != null && url.indexOf("remove") != -1)
		{
			int nRows = 0;
			try {
				JSONObject js = new JSONObject(flightJson);
				nRows = FlightHandler.deleteFlightByID(js.getInt("fid"));
			} catch (NumberFormatException | SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.write("{\"status\":" + nRows + "}");
		}
	}

}
